package com.gitee.qdbp.general.common.biz.settings.service;

import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.gitee.qdbp.able.exception.ServiceException;
import com.gitee.qdbp.able.jdbc.ordering.OrderPaging;
import com.gitee.qdbp.able.jdbc.paging.PageList;
import com.gitee.qdbp.able.result.ResultCode;
import com.gitee.qdbp.base.system.model.IAccount;
import com.gitee.qdbp.general.common.api.settings.model.SystemConfigCoreBean;
import com.gitee.qdbp.general.common.api.settings.model.SystemConfigCoreUpdate;
import com.gitee.qdbp.general.common.api.settings.model.SystemConfigCoreWhere;
import com.gitee.qdbp.general.common.api.settings.model.SystemConfigCustomizeBean;
import com.gitee.qdbp.general.common.api.settings.model.SystemConfigCustomizeUpdate;
import com.gitee.qdbp.general.common.api.settings.model.SystemConfigCustomizeWhere;
import com.gitee.qdbp.general.common.api.settings.params.UpdateCustomizeValueParams;
import com.gitee.qdbp.general.common.api.settings.service.ISystemConfigExecutor;
import com.gitee.qdbp.general.common.biz.settings.basic.SystemConfigCoreBasic;
import com.gitee.qdbp.general.common.biz.settings.basic.SystemConfigCustomizeBasic;
import com.gitee.qdbp.general.common.enums.ConfigDataType;
import com.gitee.qdbp.tools.utils.VerifyTools;

/**
 * 系统配置业务处理类
 *
 * @author zhh
 * @version 170802
 */
@Service
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
public class SystemConfigExecutor implements ISystemConfigExecutor {

    /** 日志对象 **/
    private static final Logger log = LoggerFactory.getLogger(SystemConfigExecutor.class);

    @Autowired
    private SystemConfigCoreBasic systemConfigCoreBasic;
    @Autowired
    private SystemConfigCustomizeBasic systemConfigCustomizeBasic;

    @Override
    @Transactional(readOnly = true)
    public PageList<SystemConfigCoreBean> listCoreRecord(SystemConfigCoreWhere where, OrderPaging paging)
            throws ServiceException {
        if (VerifyTools.isBlank(where.getSceneType())) {
            log.error("params is null: SceneType");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }

        // 查询默认配置
        return systemConfigCoreBasic.list(where, paging);
    }

    @Override
    public String createCoreRecord(SystemConfigCoreBean model, IAccount me) throws ServiceException {
        String msg = "Failed to create SystemConfig. ";

        if (VerifyTools.isBlank(me)) {
            log.error(msg + "params is null: me");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        if (VerifyTools.isBlank(model)) {
            log.error(msg + "params is null: model");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }

        // 参数验证
        if (VerifyTools.isBlank(model.getSceneType())) {
            log.error(msg + "params is null: SceneType");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        if (VerifyTools.isBlank(model.getConfigKey())) {
            log.error(msg + "params is null: ConfigKey");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        if (VerifyTools.isBlank(model.getConfigName())) {
            log.error(msg + "params is null: ConfigName");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }

        // 业务逻辑
        model.setId(null); // 主键由Basic生成, 不允许外部传入

        // 向gn_system_config表插入记录
        systemConfigCoreBasic.create(model);

        return model.getId();
    }

    @Override
    public void updateCoreRecord(SystemConfigCoreUpdate model, IAccount me) throws ServiceException {
        String msg = "Failed to update SystemConfig. ";

        if (VerifyTools.isBlank(me)) {
            log.error(msg + "params is null: me");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        if (VerifyTools.isBlank(model)) {
            log.error(msg + "params is null: model");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }

        String scene = model.getSceneType();
        if (VerifyTools.isBlank(scene) && model.getWhere() != null) {
            scene = model.getWhere().getSceneType();
        }
        if (VerifyTools.isBlank(scene)) {
            log.error(msg + "params is null: SceneType");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }

        String id = model.getId();
        if (VerifyTools.isBlank(id) && model.getWhere() != null) {
            id = model.getWhere().getId();
        }
        if (VerifyTools.isBlank(id)) {
            log.error(msg + "params is null: id");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }

        // 原始记录检查
        SystemConfigCoreBean older = systemConfigCoreBasic.findById(id);
        if (older == null) {
            log.error(msg + "record is not found. id=" + id);
            throw new ServiceException(ResultCode.RECORD_NOT_EXIST);
        }

        SystemConfigCoreUpdate newer = createChangedModel(model, older);

        if (newer != null) {
            // 更新gn_system_config表的记录
            systemConfigCoreBasic.update(newer, false);
        }

    }

    @Override
    public void deleteCoreRecordByIds(String scene, List<String> ids, IAccount me) throws ServiceException {
        String msg = "Failed to delete SystemConfig. ";

        if (VerifyTools.isBlank(me)) {
            log.error(msg + "params is null: me");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        if (VerifyTools.isBlank(scene)) {
            log.error(msg + "params is null: SceneType");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        if (VerifyTools.isBlank(ids)) {
            log.error(msg + "params is null: ids");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }

        // 删除gn_system_config表的记录
        systemConfigCoreBasic.deleteByIds(ids, false);

        { // 删除gn_system_customize表的记录
            SystemConfigCustomizeWhere where = new SystemConfigCustomizeWhere();
            where.setParentIds(ids);
            systemConfigCustomizeBasic.delete(where, false);
        }
    }

    @Override
    public void deleteCoreRecordByKeys(String scene, List<String> keys, IAccount me) throws ServiceException {
        String msg = "Failed to delete SystemConfig. ";

        if (VerifyTools.isBlank(me)) {
            log.error(msg + "params is null: me");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        if (VerifyTools.isBlank(scene)) {
            log.error(msg + "params is null: SceneType");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        if (VerifyTools.isBlank(keys)) {
            log.error(msg + "params is null: keys");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }

        // 删除gn_system_config表的记录
        systemConfigCoreBasic.deleteByKeys(keys, false);
    }

    @Override
    public void updateCustomizeValue(UpdateCustomizeValueParams params, IAccount me) throws ServiceException {
        String msg = "Failed to update SystemConfigCustomizeValue. ";

        if (VerifyTools.isBlank(me)) {
            log.error(msg + "params is null: me");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        String configKey = params.getConfigKey();
        if (VerifyTools.isBlank(params.getConfigKey())) {
            log.error(msg + "params is null: configKey");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        String sceneType = params.getSceneType();
        if (VerifyTools.isBlank(params.getSceneType())) {
            log.error(msg + "params is null: SceneType");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        ConfigDataType dataType = params.getDataType();
        if (VerifyTools.isBlank(params.getDataType())) {
            log.error(msg + "params is null: dataType");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }

        SystemConfigCoreBean original;
        { // 原始记录检查
            SystemConfigCoreWhere w = new SystemConfigCoreWhere();
            w.setConfigKey(configKey);
            w.setSceneType(sceneType);
            w.setDataType(dataType);
            original = systemConfigCoreBasic.find(w);
            if (original == null) {
                String m = msg + "record is not found. configKey={}, sceneType={}, dataType={}";
                log.error(m, configKey, sceneType, dataType);
                throw new ServiceException(ResultCode.RECORD_NOT_EXIST);
            }
        }

        // 判断是否允许修改
        if (!original.getEditable()) {
            log.error(msg + "record cannot edit, editable=false. configKey=" + configKey);
            throw new ServiceException(ResultCode.RECORD_STATE_ERROR);
        }

        String configValue = params.getConfigValue();
        String configText = params.getConfigText();
        SystemConfigCustomizeBean older;
        { // 原始记录检查
            SystemConfigCustomizeWhere w = new SystemConfigCustomizeWhere();
            w.setTenantCode(params.getTenantCode());
            w.setConfigKey(configKey);
            w.setSceneType(sceneType);
            w.setDataType(dataType);
            older = systemConfigCustomizeBasic.find(w);
        }
        if (older == null) { // 不存在, 新增
            SystemConfigCustomizeBean bean = new SystemConfigCustomizeBean();
            bean.setSceneType(sceneType);
            bean.setDataType(dataType);
            bean.setConfigKey(configKey);
            bean.setConfigValue(configValue);
            bean.setConfigText(params.getConfigText());
            bean.setParentId(original.getId());
            systemConfigCustomizeBasic.create(bean);
        } else { // 已存在, 修改
            boolean changed = false;
            SystemConfigCustomizeUpdate newer = new SystemConfigCustomizeUpdate();
            newer.getWhere(true).setSceneType(sceneType);
            newer.getWhere(true).setDataType(dataType);
            newer.getWhere(true).setConfigKey(configKey);
            newer.getWhere(true).setTenantCode(params.getTenantCode());
            newer.setUpdateTimeToCurrent(true);
            if (VerifyTools.isChanged(configValue, older.getConfigValue())) {
                changed = true;
                if (VerifyTools.isBlank(configValue)) {
                    newer.setConfigValueToNull(true);
                } else {
                    newer.setConfigValue(configValue); // 配置项值(程序使用)
                }
            }
            if (VerifyTools.isChanged(configText, older.getConfigText())) {
                changed = true;
                if (VerifyTools.isBlank(configText)) {
                    newer.setConfigTextToNull(true);
                } else {
                    newer.setConfigText(configText); // 配置项值的显示文本
                }
            }
            if (changed) {
                systemConfigCustomizeBasic.update(newer, false);
            }
        }
    }

    @Override
    public void deleteCustomizeValueByIds(String scene, List<String> ids, IAccount me) throws ServiceException {

        String msg = "Failed to delete SystemConfigCustomizeValue. ";

        if (VerifyTools.isBlank(me)) {
            log.error(msg + "params is null: me");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        if (VerifyTools.isBlank(scene)) {
            log.error(msg + "params is null: SceneType");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        if (VerifyTools.isBlank(ids)) {
            log.error(msg + "params is null: ids");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }

        // 删除gn_system_config表的记录
        systemConfigCustomizeBasic.deleteByIds(ids, false);
    }

    @Override
    public void deleteCustomizeValueByKeys(String scene, List<String> configKeys, IAccount me) throws ServiceException {

        String msg = "Failed to delete SystemConfigCustomizeValue. ";

        if (VerifyTools.isBlank(me)) {
            log.error(msg + "params is null: me");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        if (VerifyTools.isBlank(scene)) {
            log.error(msg + "params is null: SceneType");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }
        if (VerifyTools.isBlank(configKeys)) {
            log.error(msg + "params is null: configKeys");
            throw new ServiceException(ResultCode.PARAMETER_IS_REQUIRED);
        }

        // 删除gn_system_config表的记录
        systemConfigCustomizeBasic.deleteByKeys(configKeys, false);
    }

    /**
     * 创建一个新的对象, 只包含改动过的字段
     *
     * @author zhh
     * @param model 目标对象(一般是参数传入的)
     * @param older 源对象(一般是从数据库查询得到的)
     * @return 只包含有更新的字段对象
     */
    private SystemConfigCoreUpdate createChangedModel(SystemConfigCoreUpdate model, SystemConfigCoreBean older) {
        SystemConfigCoreUpdate newer = new SystemConfigCoreUpdate();
        newer.setWhere(model.getWhere());

        boolean changed = false;
        newer.setId(model.getId()); // 主键

        if (VerifyTools.isChanged(model.getCategoryCode(), older.getCategoryCode())) {
            changed = true;
            newer.setCategoryCode(model.getCategoryCode()); // 配置项所属分类编号
        }
        if (VerifyTools.isChanged(model.getConfigName(), older.getConfigName())) {
            changed = true;
            newer.setConfigName(model.getConfigName()); // 配置项名称
        }
        if (VerifyTools.isChanged(model.getConfigKey(), older.getConfigKey())) {
            changed = true;
            newer.setConfigKey(model.getConfigKey()); // 配置项KEY
        }
        if (VerifyTools.isChanged(model.getConfigValue(), older.getConfigValue())) {
            changed = true;
            newer.setConfigValue(model.getConfigValue()); // 配置项值(程序使用)
        }
        if (VerifyTools.isChanged(model.getConfigText(), older.getConfigText())) {
            changed = true;
            newer.setConfigText(model.getConfigText()); // 配置项值的显示文本
        }
        if (VerifyTools.isChanged(model.getConfigDesc(), older.getConfigDesc())) {
            changed = true;
            newer.setConfigDesc(model.getConfigDesc()); // 配置项描述
        }
        if (VerifyTools.isChanged(model.getSortIndex(), older.getSortIndex())) {
            changed = true;
            newer.setSortIndex(model.getSortIndex()); // 排序值(越小越靠前)
        }
        if (VerifyTools.isChanged(model.getEditable(), older.getEditable())) {
            changed = true;
            newer.setEditable(model.getEditable()); // 是否可修改
        }
        if (VerifyTools.isChanged(model.getVisible(), older.getVisible())) {
            changed = true;
            newer.setVisible(model.getVisible()); // 是否显示
        }
        if (VerifyTools.isChanged(model.getOptions(), older.getOptions())) {
            changed = true;
            newer.setOptions(model.getOptions()); // 选项
        }
        if (VerifyTools.isChanged(model.getUsingState(), older.getUsingState())) {
            changed = true;
            newer.setUsingState(model.getUsingState()); // 启用状态(1.正常|2.未启用)
        }
        // if (VerifyTools.isChanged(model.getDataState(), older.getDataState())) {
        //     changed = true;
        //     newer.setDataState(model.getDataState()); // 数据状态:0为正常|其他为删除
        // }
        // if (Boolean.TRUE.equals(model.isConfigModuleToNull())) {
        //     changed = true;
        //     newer.setConfigModuleToNull(true); // 配置项所属模块或分组更新为空值
        // }
        // if (Boolean.TRUE.equals(model.isConfigNameToNull())) {
        //     changed = true;
        //     newer.setConfigNameToNull(true); // 配置项名称更新为空值
        // }
        // if (Boolean.TRUE.equals(model.isConfigKeyToNull())) {
        //     changed = true;
        //     newer.setConfigKeyToNull(true); // 配置项KEY更新为空值
        // }
        if (Boolean.TRUE.equals(model.isConfigValueToNull())) {
            changed = true;
            newer.setConfigValueToNull(true); // 配置项值(程序使用)更新为空值
        }
        if (Boolean.TRUE.equals(model.isConfigTextToNull())) {
            changed = true;
            newer.setConfigTextToNull(true); // 配置项值的显示文本更新为空值
        }
        if (Boolean.TRUE.equals(model.isConfigDescToNull())) {
            changed = true;
            newer.setConfigDescToNull(true); // 配置项描述更新为空值
        }
        // if (Boolean.TRUE.equals(model.isSortIndexToNull())) {
        //     changed = true;
        //     newer.setSortIndexToNull(true); // 排序值(越小越靠前)更新为空值
        // }
        if (VerifyTools.isNotBlank(model.getSortIndexAdd()) && model.getSortIndexAdd() != 0) {
            changed = true;
            newer.setSortIndexAdd(model.getSortIndex()); // 排序值(越小越靠前)的增加值
        }
        // if (Boolean.TRUE.equals(model.isEditableToNull())) {
        //     changed = true;
        //     newer.setEditableToNull(true); // 是否可修改更新为空值
        // }
        // if (Boolean.TRUE.equals(model.isVisibleToNull())) {
        //     changed = true;
        //     newer.setVisibleToNull(true); // 是否显示更新为空值
        // }
        // if (Boolean.TRUE.equals(model.isOptionsToNull())) {
        //     changed = true;
        //     newer.setOptionsToNull(true); // 选项更新为空值
        // }
        // if (Boolean.TRUE.equals(model.isUsingStateToNull())) {
        //     changed = true;
        //     newer.setUsingStateToNull(true); // 启用状态(1.正常|2.未启用)更新为空值
        // }
        return changed ? newer : null;

    }

}
